import Menu from 'ant-design-vue/es/menu'
import Icon from 'ant-design-vue/es/icon'

const { Item, SubMenu } = Menu

export default {
    name: 'SMenu',
    props: {
        menu: {
            type: Array,
            required: true
        },
        theme: {
            type: String,
            required: false,
            default: 'dark'
        },
        mode: {
            type: String,
            required: false,
            default: 'inline'
        },
        collapsed: {
            type: Boolean,
            required: false,
            default: false
        }
    },
    data() {
        return {
            openKeys: [],
            selectedKeys: [],
            cachedOpenKeys: []
        }
    },
    computed: {
        rootSubmenuKeys: vm => {
            const keys = []
            vm.menu.forEach(item => keys.push(item.path))
            return keys
        }
    },
    mounted() {
        this.updateMenu()
    },
    watch: {
        collapsed(val) {
            if (val) {
                this.cachedOpenKeys = this.openKeys.concat()
                this.openKeys = []
            } else {
                this.openKeys = this.cachedOpenKeys
            }
        },
        $route: function() {
            this.updateMenu()
        }
    },
    methods: {
        // select menu item
        onOpenChange(openKeys) {

            // 在水平模式下时执行，并且不再执行后续
            if (this.mode === 'horizontal') {
                this.openKeys = openKeys
                return
            }
            // 非水平模式时
            const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
            if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
                this.openKeys = openKeys
            } else {
                this.openKeys = latestOpenKey ? [latestOpenKey] : []
            }
        },
        updateMenu() {
            try {

                const routes = this.$route.matched.concat()
                const { hidden } = this.$route.meta
                if (routes.length >= 3 && hidden) {
                    try {
                        routes.pop()
                        this.selectedKeys = [routes[routes.length - 1].path]
                    } catch (error) {
                        console.log(error);
                    }
                } else {
                    try {
                        this.selectedKeys = [routes.pop().path];
                    } catch (error) {
                        this.selectedKeys = [this.$route.path];
                    }
                }
                const openKeys = []
                if (this.mode === 'inline') {
                    routes.forEach(item => {
                        openKeys.push(item.path)
                    })
                }
                if (!this.selectedKeys || this.selectedKeys[0].indexOf(":") < 0) {
                    this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
                }
            } catch (error) {
                console.log(error);
            }
        },

        // render
        renderItem(menu) {
            if (!menu.hidden) {
                return menu.children && !menu.alwaysShow ? this.renderSubMenu(menu) : this.renderMenuItem(menu)
            }
            return null
        },
        renderMenuItem(menu) {
            const target = menu.meta.target || null
            const tag = target && 'a' || 'router-link'
            let props = { to: { name: menu.name } }
            if (menu.route && menu.route === '0') {
                props = { to: { path: menu.path } }
            }

            const attrs = { href: menu.path, target: menu.meta.target }

            if (menu.children && menu.alwaysShow) {
                // 把有子菜单的 并且 父菜单是要隐藏子菜单的
                // 都给子菜单增加一个 hidden 属性
                // 用来给刷新页面时， selectedKeys 做控制用
                menu.children.forEach(item => {
                    item.meta = Object.assign(item.meta, { hidden: true })
                })
            }

            return ( <
                Item {... { key: menu.path } } >
                <
                tag {... { props, attrs } } > { this.renderIcon(menu.meta.icon) } <
                span > { menu.meta.title } < /span> < /
                tag > <
                /Item>
            )
        },
        renderSubMenu(menu) {
            const itemArr = []
            if (!menu.alwaysShow) {
                menu.children.forEach(item => itemArr.push(this.renderItem(item)))
            }
            return ( <
                SubMenu {... { key: menu.path } } >
                <
                span slot = "title" > { this.renderIcon(menu.meta.icon) } <
                span > { menu.meta.title } < /span> < /
                span > { itemArr } <
                /SubMenu>
            )
        },
        renderIcon(icon) {
            if (icon === 'none' || icon === undefined) {
                return null
            }
            const props = {}
            typeof(icon) === 'object' ? props.component = icon: props.type = icon
            return ( <
                Icon {... { props } }
                />
            )
        }
    },

    render() {
        const { mode, theme, menu } = this
        const props = {
            mode: mode,
            theme: theme,
            openKeys: this.openKeys
        }
        const on = {
            select: obj => {
                this.selectedKeys = obj.selectedKeys
                this.$emit('select', obj)
            },
            openChange: this.onOpenChange
        }

        const menuTree = menu.map(item => {
                if (item.hidden) {
                    return null
                }
                return this.renderItem(item)
            })
            // {...{ props, on: on }}
        return ( <
            Menu vModel = { this.selectedKeys } {... { props, on: on } } > { menuTree } <
            /Menu>
        )
    }
}